package com.nsn.vs.sdm.util.sftp;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.nsn.vs.sdm.util.collection.UtilCollection;

import net.sf.opensftp.SftpException;
import net.sf.opensftp.SftpResult;
import net.sf.opensftp.SftpSession;
import net.sf.opensftp.SftpUtil;
import net.sf.opensftp.SftpUtilFactory;
import net.sf.opensftp.impl.SftpFileImpl;

/**
 * Utilities for SFTP operations, e.g. login, fetch file and etc.
 * 
 * @author Jeccy.Zhao
 *
 */
public class UtilSftp
{
	/**
	 * LOGGER
	 */
	private static Logger LOGGER = Logger.getLogger(UtilSftp.class);
	
	/**
	 * Host
	 */
	private String host;
	
	/**
	 * User name for authentication
	 */
	private String userName;
	
	/**
	 * User password for authentication
	 */
	private String password;
	
	/**
	 * Instance of SFTP utility
	 */
	private static SftpUtil sftpUtil = SftpUtilFactory.getSftpUtil();
	
	/**
	 * Instance of SFTP session
	 */
	private SftpSession session = null;
	
	/**
	 * Flag that indicates session connected or not
	 */
	private boolean isConnected = false;
	
	/**
	 * The sole constructor
	 * 
	 * @param host
	 * @param userName
	 * @param password
	 */
	public UtilSftp (String host, String userName, String password)
	{
		this.host = host;
		this.userName = userName;
		this.password = password;
	}
	
	/**
	 * Initialization
	 */
	@SuppressWarnings("unused")
	private void init ()
	{
		
	}
	
	/**
	 * Connects to the specified host
	 * 
	 * @throws SftpException
	 */
	public void connect () throws SftpException
	{
		session = sftpUtil.connectByPasswdAuth(
				host, 
				userName, 
				password, 
				SftpUtil.STRICT_HOST_KEY_CHECKING_OPTION_NO);
		
		isConnected = true;
		LOGGER.info("Successfully connected with `" + host + "`.");
	}
	
	/**
	 * Disconnects
	 * 
	 * @throws SftpException
	 */
	public void disConnect () throws SftpException
	{
		if (session != null)
		{
			sftpUtil.disconnect(session);
		}
	}
	
	/**
	 * Remote fetch file and stores to the specified destination
	 * 
	 * @param sourceFile
	 * @param destFile
	 */
	public void getFile (String sourceFile, String destFile)
	{
		sftpUtil.get(session, sourceFile, destFile);
	}
	
	/**
	 * List all entries from the specified path
	 * 
	 * @param path
	 */
	@SuppressWarnings("unchecked")
	public List<String> listEntries (String path)
	{
		sftpUtil.cd(session, path);
		SftpResult result = sftpUtil.ls(session);
		if (result != null)
		{
			List<SftpFileImpl> fileList = (List<SftpFileImpl>) result.getExtension();
			if (fileList != null)
			{
				List<String> entries = new ArrayList<String>();
				for (SftpFileImpl file : fileList)
				{
					entries.add(path + file.getName());
				}
				
				return entries;
			}
		}
		
		return null;
	}
	
	/**
	 * Obtains file entry
	 * 
	 * @param path
	 * @param file
	 * @return
	 */
	public String getFileEntry (String path, String file)
	{
		List<String> fileEntries = listEntries(path);
		if (UtilCollection.isNotEmpty(fileEntries))
		{
			for (String fileEntry : fileEntries)
			{
				if (fileEntry.contains(file))
				{
					return fileEntry;
				}
			}
		}
		
		return null;
	}
	
	public void setHost(String host)
	{
		this.host = host;
	}

	public String getHost()
	{
		return host;
	}

	public void setUserName(String userName)
	{
		this.userName = userName;
	}

	public String getUserName()
	{
		return userName;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

	public String getPassword()
	{
		return password;
	}

	public static void setSftpUtil(SftpUtil sftpUtil)
	{
		UtilSftp.sftpUtil = sftpUtil;
	}

	public static SftpUtil getSftpUtil()
	{
		return sftpUtil;
	}
	
	public SftpSession getSession()
	{
		return session;
	}

	public boolean isConnected()
	{
		return isConnected;
	}
}
